package com.xnyzc.lhy.order.entity.common.gps;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xnyzc.lhy.common.component.amap.GouldMapUtils;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.order.entity.common.order.OrderCommon;
import com.xnyzc.lhy.order.entity.gps.OaDVehicleGpsHistory;
import com.xnyzc.lhy.order.entity.order.OaCOrder;
import com.xnyzc.lhy.order.feign.amap.IAmapService;
import com.xnyzc.lhy.order.feign.statistics.FeignTrajectoryService;
import com.xnyzc.lhy.order.mapper.gps.OaDVehicleGpsHistoryMapper;
import com.xnyzc.lhy.order.mapper.system.OaSysGlobalConfigMapper;
import com.xnyzc.lhy.resource.entity.amap.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author: huxuekuo
 * @Date: 2019-07-27 10:51
 * @Description:
 */
@Component
@Slf4j
public class GpsCommon {

    @Autowired
    RedisCommon redisCommon;
    @Autowired
    OaSysGlobalConfigMapper sysGlobalConfigMapper;

    @Autowired
    OaDVehicleGpsHistoryMapper oaDVehicleGpsHistoryMapper;

    @Autowired
    OrderCommon orderCommon;

    @Autowired
    IAmapService iAmapService;

    @Autowired
    FeignTrajectoryService feignTrajectoryService;


    /**
     * 根据车辆主键的ID创建一个轨迹Key
     *
     * @param vehId 车辆主键
     * @return
     */
    public String vehKey(Long vehId) {
        return RedisPrefixConstant.GPS_VEH_KEY_PREFIX + vehId;
    }


    /**
     * 根据订单号查询历史轨迹信息
     *
     * @param orderNo 订单号
     * @return 返回经纬度集合
     */
    public List<Qd> getHistroyGpsList(String orderNo) {
        List<Qd> gpsList = new ArrayList<>();
        try {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.select(OaDVehicleGpsHistory.LNG, OaDVehicleGpsHistory.LAT);
            queryWrapper.eq(OaDVehicleGpsHistory.ORDER_NO, orderNo);
            List<OaDVehicleGpsHistory> list = oaDVehicleGpsHistoryMapper.selectList(queryWrapper);
            for (OaDVehicleGpsHistory history : list) {
                Qd add = Qd.create().add("lat", history.getLat()).add("lng", history.getLng());
                gpsList.add(add);
            }
        } catch (Exception e) {
            log.error("ORDER_HISTORY 获取历史轨迹错误,错误信息:[{}]", e);
        }
        return gpsList;
    }

    /**
     * 创建新线程获取轨迹信息
     *
     * @param order 订单实体类
     */
    public HistoryEntity addThreadHistroyGps(OaCOrder order, Date startTime, Integer type) {
        HistoryEntity result = new HistoryEntity();
        try {
            //轨迹ID
            Long gpsId = order.getGpsId();
            //服务ID'
            Long serviceId = orderCommon.getServiceId();
            //司机终端ID
            Long tid = orderCommon.getTid(String.valueOf(order.getDriverId()));
            //开启线程添加经纬
            new Thread(() -> {
                Date arriveTime = order.getArriveTime();
                if (CheckUtil.objIsEmpty(arriveTime)) {
                    arriveTime = new Date();
                }
                int page = 1;
                List<OaDVehicleGpsHistory> listHistory = new ArrayList<>();
                //从高德获轨迹
                HistoryEntity gouldHistoryGps = getGouldHistoryGps(order, page, startTime, gpsId, tid, serviceId, type, arriveTime);
                // 获取经纬度
                List<OaDVehicleGpsHistory> histories = gouldHistoryGps.getHistories();
                if (CheckUtil.collectionIsNotEmpty(histories)) {
                    listHistory.addAll(histories);
                }
                while (histories.size() == 999) {
                    page++;
                    gouldHistoryGps = getGouldHistoryGps(order, page, startTime, gpsId, tid, serviceId, type, arriveTime);
                    if (CheckUtil.objIsEmpty(gouldHistoryGps)) {
                        break;
                    }
                    histories = gouldHistoryGps.getHistories();
                    if (CheckUtil.collectionIsEmpty(histories)) {
                        break;
                    }
                    listHistory.addAll(histories);
                    if (histories.size() < 999) {
                        break;
                    }
                }
                if (listHistory.size() > 0) {
                    oaDVehicleGpsHistoryMapper.insertForeach(listHistory);
                    // ES 轨迹保存
                    // feignTrajectoryService.saveOrderTrajectory(listHistory);
                }
            }).start();
            return result;
        } catch (Exception e) {
            log.error("添加订单轨迹失败");
        }
        return result;
    }

    /**
     * 获取原始猎鹰轨迹
     *
     * @param order     订单信息
     * @param startTime
     * @return
     */
    public HistoryEntity getHistoryEntity(OaCOrder order, Date startTime, Date endTime, Integer type) {
        HistoryEntity result = new HistoryEntity();
        try {
            // 轨迹ID
            Long gpsId = order.getGpsId();
            // 服务ID'
            Long serviceId = order.getServiceId();
            // 司机终端ID
            Long tid = order.getTid();
            // 开启线程添加经纬
            int page = 1;
            List<GpsHistoryInfo> gpsHistoryInfoList = new ArrayList<>();
            // 从高德获轨迹
            HistoryEntity gouldHistoryGps = getGouldHistoryGps(order, page, startTime, gpsId, tid, serviceId, type, endTime);
            if (CheckUtil.objIsNotEmpty(gouldHistoryGps)) {
                //设置轨迹里程,轨迹时长
                result.setDistance(gouldHistoryGps.getDistance());
                result.setTime(gouldHistoryGps.getTime());
            }
            // 获取经纬度
            List<GpsHistoryInfo> gpsHistoryInfos = gouldHistoryGps.getGpsHistoryInfos();
            if (CheckUtil.collectionIsEmpty(gpsHistoryInfos)) {
                return result;
            }
            gpsHistoryInfoList.addAll(gpsHistoryInfos);
            while (gpsHistoryInfos.size() == 999) {
                page++;
                gouldHistoryGps = getGouldHistoryGps(order, page, startTime, gpsId, tid, serviceId, type, endTime);
                if (CheckUtil.objIsEmpty(gouldHistoryGps)) {
                    break;
                }
                gpsHistoryInfos = gouldHistoryGps.getGpsHistoryInfos();
                if (CheckUtil.collectionIsEmpty(gpsHistoryInfos)) {
                    break;
                }
                gpsHistoryInfoList.addAll(gpsHistoryInfos);
                if (gpsHistoryInfos.size() < 999) {
                    break;
                }
            }
            result.setGpsHistoryInfos(gpsHistoryInfoList);
            return result;
        } catch (Exception e) {
            log.error("添加订单轨迹失败");
        }
        return result;
    }


    /**
     * 获取
     *
     * @param gpsId
     * @param tid
     * @param serviceId
     * @param startTime
     * @param endTime
     * @return
     */
    public HistoryEntity getHistoryDistance(Long gpsId, Long tid, Long serviceId, Date startTime, Date endTime, Integer type) {
        HistoryEntity historyEntity = null;
        AmapGouldHistoryGps amapGouldHistoryGps = iAmapService.getHistoryGps(serviceId, gpsId, tid, startTime.getTime(), endTime.getTime(), 1, type);
        //为空则删除
        if (CheckUtil.objIsEmpty(amapGouldHistoryGps) || CheckUtil.objIsEmpty(amapGouldHistoryGps.getData())) {
            return historyEntity;
        }
        AmapGouldHistoryGps.DataBean data = amapGouldHistoryGps.getData();
        List<AmapGouldHistoryGps.DataBean.TracksBean> tracks = data.getTracks();
        if (CheckUtil.collectionIsEmpty(tracks)) {
            return historyEntity;
        }
        historyEntity = new HistoryEntity();
        for (AmapGouldHistoryGps.DataBean.TracksBean track : tracks) {
            //设置轨迹里程,轨迹时长
            historyEntity.setDistance(new BigDecimal(track.getDistance()));
            historyEntity.setTime(new BigDecimal(track.getTime()));
        }
        return historyEntity;
    }


    /**
     * 获取过滤后的经纬度信息
     *
     * @param oaCOrder  订单信息
     * @param page
     * @param startTime 开始时间
     * @param tid       终端Id
     * @param gpsId     轨迹Id
     * @param serviceId 服务ID
     * @return
     */
    public HistoryEntity getGouldHistoryGps(OaCOrder oaCOrder, int page, Date startTime, Long gpsId, Long tid, Long
            serviceId, Integer type, Date endTime) {
        if (CheckUtil.objIsEmpty(endTime)) {
            endTime = new Date();
        }
        HistoryEntity historyEntity = new HistoryEntity();
        log.info("查询历史轨迹 orderNo: " + oaCOrder.getOrderNo() + ",  服务ID: " + serviceId + ", 轨迹ID: " + gpsId + ", 终端ID: " + tid + ", 开始时间: " + startTime.getTime() + " 结束时间: " + endTime.getTime());
        List<OaDVehicleGpsHistory> listHistory = new ArrayList<>();
        List<GpsHistoryInfo> gpsHistoryInfos = new ArrayList<>();
        //从猎鹰中获取经纬度
        AmapGouldHistoryGps amapGouldHistoryGps = iAmapService.getHistoryGps(serviceId, gpsId, tid, startTime.getTime(), endTime.getTime(), page, type);
        //为空则删除
        if (CheckUtil.objIsEmpty(amapGouldHistoryGps) || CheckUtil.objIsEmpty(amapGouldHistoryGps.getData())) {
            return historyEntity;
        }
        AmapGouldHistoryGps.DataBean data = amapGouldHistoryGps.getData();
        List<AmapGouldHistoryGps.DataBean.TracksBean> tracks = data.getTracks();
        for (AmapGouldHistoryGps.DataBean.TracksBean track : tracks) {
            List<AmapGouldHistoryGps.DataBean.TracksBean.Point> points = track.getPoints();
            log.info("查询历史轨迹 orderNo: " + oaCOrder.getOrderNo() + ", 历史轨迹长度:" + points.size());
            //设置轨迹里程,轨迹时长
            historyEntity.setDistance(new BigDecimal(track.getDistance()));
            historyEntity.setTime(new BigDecimal(track.getTime()));
            //循环点位信息
            for (AmapGouldHistoryGps.DataBean.TracksBean.Point point : points) {
                if (CheckUtil.strIsNotEmpty(point.getLocation())) {
                    String[] split = point.getLocation().split(",");
                    String lng = split[0];
                    String lat = split[1];
                    //添加历史轨迹信息
                    OaDVehicleGpsHistory history = new OaDVehicleGpsHistory();
                    history.setCreateTime(endTime);
                    history.setCreateUser(oaCOrder.getDriverId());
                    history.setHistoryId(IDUtil.nextId());
                    history.setVehId(oaCOrder.getVehicleId());
                    history.setUpdateUser(oaCOrder.getDriverId());
                    history.setDriverId(oaCOrder.getDriverId());
                    history.setOrderNo(oaCOrder.getOrderNo());
                    history.setUpdateTime(endTime);
                    history.setLat(lat);
                    history.setLng(lng);
                    history.setVehType(oaCOrder.getVehicleType());
                    listHistory.add(history);
                    //
                    GpsHistoryInfo gpsHistoryInfo = new GpsHistoryInfo();
                    gpsHistoryInfo.setAccuracy(point.getAccuracy());
                    gpsHistoryInfo.setDirection(point.getDirection());
                    gpsHistoryInfo.setHeight(point.getHeight());
                    gpsHistoryInfo.setLocatetime(point.getLocatetime());
                    gpsHistoryInfo.setLocation(point.getLocation());
                    gpsHistoryInfo.setSpeed(point.getSpeed());
                    gpsHistoryInfos.add(gpsHistoryInfo);
                }
            }
        }
        historyEntity.setHistories(listHistory);
        historyEntity.setGpsHistoryInfos(gpsHistoryInfos);
        return historyEntity;
    }


    /**
     * 批量上传经纬度信息
     *
     * @param gpsId           轨迹ID
     * @param tid             终端ID
     * @param serviceId       服务ID
     * @param historyEntities 点位集合
     * @return
     */
    public Boolean uploadTrack(Long gpsId, Long tid, Long serviceId, List<Object> historyEntities) {
        return GouldMapUtils.uploadTrack(serviceId, tid, gpsId, historyEntities);
    }
}
